package com.fengzai.election;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Created by  峰仔  on 2017-08-12
 */
public class MasterSelector {
    private CuratorFramework curatorFramework;
    private CountDownLatch countDownLatch = new CountDownLatch(1);

    public MasterSelector(CuratorFramework curatorFramework) {
        this.curatorFramework = curatorFramework;
    }

    /**
     * @param serverName 参与选主的服务器名称
     * @throws Exception
     */
    public void start(String serverName) throws Exception {
        //看看有没有地主  有就不要抢了
        Stat exists = curatorFramework.checkExists().forPath("/Landlord");
        //如果此节点下有一个子节点表示已经有主服务器了 就不用进行选举  只需要监听就行  反之则表示主节点挂了 就要进行抢主
        if (exists == null) {
            try {
                String exist = curatorFramework.create().withMode(CreateMode.EPHEMERAL).forPath("/Landlord", serverName.getBytes());
                System.out.println(serverName + "  -->   已经成功的成为了新的地主了");

                TimeUnit.SECONDS.sleep(3);
                //抢到后  停留3秒后  模拟故障  删除节点 并退出集群
                curatorFramework.delete().forPath("/Landlord");
                countDownLatch.countDown();
            } catch (Exception e) {
                // e.printStackTrace();
            }
        }
        //能到这里表示抢地主失败 只能监听等下次机会了
        NodeCache nodeCache = new NodeCache(curatorFramework, "/Landlord", false);
        nodeCache.getListenable().addListener(() -> {
            ChildData currentData = nodeCache.getCurrentData();
            //表示主节点挂了可以开始抢地主了
            if (currentData == null) {
                start(serverName);
            }
        });
        nodeCache.start(true);
        countDownLatch.await();
    }
}
